home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / batchut / batcsh10.zip / bat2csh.l < prev    next >
Text File  |  1994-01-12  |  18KB  |  709 lines

  1. %{
  2. /**************************************************************************/
  3. /*    MODULE: bat2csh.l                                                   */
  4. /*   PURPOSE: converts dos batch files to unix csh files                  */
  5. /*    AUTHOR: Bill Pierpoint                                              */
  6. /*       LEX: FLEX Version 2.3.7                                          */
  7. /*  COMPILER: Borland C Version 3.1                                       */
  8. /* COPYRIGHT: None.  Public Domain.                                       */
  9. /*   VERSION: 1.00                                                        */
  10. /*   RELEASE: January 12, 1994                                            */
  11. /**************************************************************************/
  12. #include <stdc.h>
  13. #ifdef __BORLANDC__
  14. #pragma hdrstop
  15. #endif
  16.  
  17. #define putstr(s)    fputs((s),  stdout)
  18. #define puttab()    fputc('\t', stdout)
  19. #define putln()        fputc('\n', stdout)
  20. #define token(t)    (t)
  21. #define ckeol(t)    do { if((t)==EOL) { puts(" ### SYNTAX ERROR ###"); \
  22.                           errorcount++; return;} } while(0)
  23. #define cktok(t, x)    do { if((t)!=(x)) { puts(" ### SYNTAX ERROR ###"); \
  24.                           errorcount++; eattokens(); return;} } while(0)
  25.  
  26. typedef struct
  27. {
  28.     int token;
  29.     void (*fn)(void);
  30. } FNTBL;
  31.  
  32. #define STRBUFSIZE    129
  33. char textbuf[STRBUFSIZE];
  34.  
  35. /**************************************************************************/
  36. /* token enumeration                                                      */
  37. /**************************************************************************/
  38. enum {
  39.     OTHER=1,
  40.     EOL,
  41.     SPACE,
  42.     VARIABLE,
  43.     PARAMETER,
  44.     WORD,
  45.     INIT_CALL,
  46.     INIT_ECHO,
  47.     INIT_FOR,
  48.     INIT_GOTO,
  49.     INIT_IF,
  50.     INIT_PATH,
  51.     INIT_PAUSE,
  52.     INIT_REM,
  53.     INIT_SET,
  54.     INIT_SHIFT,
  55.     INIT_LABEL,
  56.     INIT_COMMAND,
  57.     ECHO_ON,
  58.     ECHO_OFF,
  59.     ECHO_DOT,
  60.     IF_NOT,
  61.     IF_ERRORLEVEL,
  62.     IF_EXIST,
  63.     FOR_VARIABLE,
  64.     FOR_IN,
  65.     FOR_WORDLIST,
  66.     FOR_DO
  67. };
  68.  
  69. /**************************************************************************/
  70. /* function prototypes                                                    */
  71. /**************************************************************************/
  72. /* support functions */
  73. char *cvt_parameter(char *s);
  74. char *cvt_variable(char *s);
  75. char *cvt_for_variable(char *s);
  76. char *cvt_set_variable(int token);
  77. char *cvt_token(int token, char *s);
  78. int dispatch(void);
  79. void indent(void);
  80. int lex(void);
  81. void putbacktoken(void);
  82. void puttokln(int token, char *start, char *end);
  83. int  reporterrors(void);
  84. void terminate(void);
  85. char *tr(char *s, int oldch, int newch);
  86.  
  87. /* keyword functions */
  88. void kw_call(void);
  89. void kw_command(void);
  90. void kw_echo(void);
  91. void kw_for(void);
  92. void kw_goto(void);
  93. void kw_if(void);
  94. void kw_label(void);
  95. void kw_ln(void);
  96. void kw_path(void);
  97. void kw_pause(void);
  98. void kw_remark(void);
  99. void kw_set(void);
  100. void kw_shift(void);
  101.  
  102. %}
  103.  
  104. digit        [0-9]
  105. delim        [ \t=;]
  106. name        [-{}()&#!~$a-zA-Z0-9]
  107. legal        [!-$&-:<>-~]
  108. other        .
  109.  
  110. %x ECHOS
  111. %x TEXT
  112. %x FOR
  113.  
  114. %%
  115. <INITIAL>^"@"            ;
  116. <INITIAL>call            return token(INIT_CALL);
  117. <INITIAL>echo            return token(INIT_ECHO);
  118. <INITIAL>for            return token(INIT_FOR);
  119. <INITIAL>goto            return token(INIT_GOTO);
  120. <INITIAL>if            return token(INIT_IF);
  121. <INITIAL>pause            return token(INIT_PAUSE);
  122. <INITIAL>rem            return token(INIT_REM);
  123. <INITIAL>set            return token(INIT_SET);
  124. <INITIAL>path            return token(INIT_PATH);
  125. <INITIAL>shift            return token(INIT_SHIFT);
  126. <INITIAL>^":"{name}+        return token(INIT_LABEL);
  127. <INITIAL>^":"            return token(INIT_REM);
  128. <INITIAL>{name}+        return token(INIT_COMMAND);
  129. <ECHOS>on            return token(ECHO_ON);
  130. <ECHOS>off            return token(ECHO_OFF);
  131. <ECHOS>"."            return token(ECHO_DOT);
  132. <TEXT>not            return token(IF_NOT);
  133. <TEXT>errorlevel        return token(IF_ERRORLEVEL);
  134. <TEXT>exist            return token(IF_EXIST);
  135. <TEXT>{delim}+            return token(SPACE);
  136. <TEXT>"%"{name}+"%"           return token(VARIABLE);
  137. <TEXT>"%"{digit}        return token(PARAMETER);
  138. <TEXT,FOR>%%{name}+        return token(FOR_VARIABLE);
  139. <FOR>in                return token(FOR_IN);
  140. <FOR>do                return token(FOR_DO);
  141. <FOR>"("[^)]+")"        return token(FOR_WORDLIST);
  142. <INITIAL,ECHOS,TEXT,FOR>"\n"    return token(EOL);
  143. <INITIAL,ECHOS,FOR>{delim}+    ;
  144. <ECHOS,TEXT>{legal}+        return token(WORD);
  145. <INITIAL,ECHOS,TEXT,FOR>{other}    return token(OTHER);
  146.  
  147. %%
  148.  
  149. #ifdef __BORLANDC__
  150. #pragma option -w
  151. #endif
  152.  
  153. /**************************************************************************/
  154. /* global variables                                                       */
  155. /**************************************************************************/
  156. int cmdtoken;         /* first token in each batch line */
  157. int errorcount=0;     /* syntax error counter */
  158. int errorlevelflag=0; /* control use of "set errorlevel=$status" */
  159. int indentlevel=0;    /* indent level of output */
  160.  
  161. /**************************************************************************/
  162. /* support functions                                                      */
  163. /**************************************************************************/
  164. /* report any errors */
  165. int reporterrors()
  166. {
  167.     char s[7];
  168.  
  169.     if (errorcount) {
  170.         itoa(errorcount, s, 10);
  171.         fputs("\n\nNUMBER OF ERRORS = ", stderr);
  172.         fputs(s, stderr);
  173.         fputs("\n\n", stderr);
  174.         return EXIT_FAILURE;
  175.     }
  176.     return EXIT_SUCCESS;
  177. }
  178.  
  179. /* abnormal termination */
  180. void terminate(void)
  181. {
  182.     putln();
  183.     puts(" ### PREMATURE END-OF-FILE ###");
  184.     errorcount++;
  185.     exit(reporterrors());
  186. }
  187.  
  188. /* wrapper for yylex */
  189. int lex(void)
  190. {
  191.     int result;         /* return result */
  192.     static int count=0; /* count number of times yylex returns 0 */
  193.     
  194.     result = yylex();
  195.     if (!result) {
  196.         if (count==1) {
  197.             terminate();
  198.         } else {    /* handle possible premature eof */
  199.             count++;
  200.             result = EOL;
  201.         }
  202.     }
  203.     return result;
  204. }
  205.  
  206. /* indent output based on global indentlevel */
  207. void indent(void)
  208. {
  209.     int i;
  210.     
  211.     for (i=0; i<indentlevel; i++) puttab();
  212. }
  213.  
  214. /* put token back to input stream */
  215. /* note: flex 2.3.7 yyless(0) not available in section 3 */
  216. void putbacktoken(void)
  217. {
  218.     int i;
  219.  
  220.     for (i=yyleng-1; i>=0; i--) {
  221.         unput(yytext[i]);
  222.     }
  223. }
  224.  
  225. /* translate character in string s */
  226. char *tr(char *s, int oldch, int newch)
  227. {
  228.     char *sp = s;
  229.  
  230.     do {
  231.         if (*sp==oldch) *sp=newch;
  232.     } while (*sp++);
  233.     return s;
  234. }
  235.  
  236. /* convert replaceable parameter, e.g. %1 -> $1 */
  237. char *cvt_parameter(char *s)
  238. {
  239.     strcpy(textbuf, s);
  240.     *textbuf='$';
  241.     return textbuf;
  242. }
  243.  
  244. /* convert variable, e.g. %PATH% -> ${path} */
  245. char *cvt_variable(char *s)
  246. {
  247.     char *sp;
  248.  
  249.     strcpy(textbuf, "${");
  250.     sp = s;
  251.     sp++;
  252.     strncat(textbuf, sp, yyleng-2);
  253.     strcat(textbuf, "}");
  254.     return strlwr(textbuf);
  255. }
  256.  
  257. /* convert variable used with 'for' keyword, e.g. %%F -> ${f} */
  258. char *cvt_for_variable(char *s)
  259. {
  260.     char *sp;
  261.  
  262.     strcpy(textbuf, "${");
  263.     sp = s;
  264.     sp += 2;
  265.     strncat(textbuf, sp, yyleng-2);
  266.     strcat(textbuf, "}");
  267.     return strlwr(textbuf);
  268. }
  269.  
  270. /* convert variable used with set keyword, e.g. ${f} -> f */ 
  271. char *cvt_set_variable(int token)
  272. {
  273.     int len;
  274.  
  275.     switch(token) {
  276.     case VARIABLE:
  277.     case FOR_VARIABLE:
  278.         len = strlen(textbuf)-2;
  279.         memmove(textbuf, textbuf+2, len);
  280.         textbuf[len-1]='\0';
  281.         break;
  282.     default:
  283.         break;
  284.     }
  285.     return textbuf;
  286. }
  287.  
  288. /* convert from batch format to csh format */
  289. char *cvt_token(int token, char *s)
  290. {
  291.     char *sp, *tp=textbuf;
  292.  
  293.     switch(token) {
  294.     case PARAMETER:
  295.         if (s) cvt_parameter(s);
  296.         else   cvt_parameter(yytext);
  297.         break;
  298.     case VARIABLE:
  299.         if (s) cvt_variable(s);
  300.         else   cvt_variable(yytext);
  301.         break;
  302.     case FOR_VARIABLE:
  303.         if (s) cvt_for_variable(s);
  304.         else   cvt_for_variable(yytext);
  305.         break;
  306.     case SPACE:
  307.         if (s) strcpy(textbuf, s);
  308.         else   strcpy(textbuf, yytext);
  309.         /* translate delimiter if set or path */
  310.         if (cm